package com.mls.fivedistrict.server.impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.util.StringUtil;
import com.mls.fivedistrict.common.PageFilter;
import com.mls.fivedistrict.common.ServiceResponse;
import com.mls.fivedistrict.dao.CalculateMapper;
import com.mls.fivedistrict.enums.CalculateSourceEnum;
import com.mls.fivedistrict.enums.CalculateTypeEnum;
import com.mls.fivedistrict.enums.ResponseCode;
import com.mls.fivedistrict.exception.CustomerException;
import com.mls.fivedistrict.pojo.Calculate;
import com.mls.fivedistrict.pojo.CalculateExample;
import com.mls.fivedistrict.pojo.User;
import com.mls.fivedistrict.pojo.UserExample;
import com.mls.fivedistrict.server.CalculateService;
import com.mls.fivedistrict.server.UserService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Optional;

/**
 * Created by chenxiuxiang on 2018/3/23.
 */
@Service("calculateService")
public class CalculateServiceImpl implements CalculateService {

    @Resource(name = "calculateMapper")
    CalculateMapper calculateMapper;
    @Resource(name = "userService")
    UserService userService;

    @Override
    public ServiceResponse addCalculate(Calculate calculate) {
        Long userId = calculate.getUserId();
        ServiceResponse userServiceUser = userService.getUser(userId);
        if (userServiceUser.getState().equals(ResponseCode.SUCCESS.getCode())) {
            User user = (User) userServiceUser.getData();
            User newUser = new User();
            newUser.setId(userId);
            newUser.setPhone(user.getPhone());
            if (user.getCalculate() == null) {
                newUser.setCalculate(calculate.getValue());
            } else {
                newUser.setCalculate(user.getCalculate() + calculate.getValue());
            }
            userService.editUser(newUser, userId);
            calculate.setCreateDate(new Date());
            if (StringUtil.isEmpty(calculate.getSource())) {
                calculate.setSource(CalculateSourceEnum.TASK.getValue());
            }
            calculate.setIsDelete(false);
            int insert = calculateMapper.insertSelective(calculate);
            return insert > 0 ? ServiceResponse.createSuccessResponse() : ServiceResponse.createErrorResponse("添加失败");

        }
        return ServiceResponse.createErrorResponse("用户不存在");

    }

    @Override
    public ServiceResponse deleteCalculate(Long id) {
        CalculateExample calculateExample = new CalculateExample();
        calculateExample.createCriteria().andIdEqualTo(id);
        Calculate calculate = calculateMapper.selectByPrimaryKey(id);
        if (calculate == null) {
            return ServiceResponse.createErrorResponse("算力不存在");
        }
        Calculate newCalculate = new Calculate();
        newCalculate.setIsDelete(true);
        newCalculate.setId(calculate.getId());
        int row = calculateMapper.updateByPrimaryKeySelective(newCalculate);
        return row > 0 ? ServiceResponse.createSuccessResponse("操作成功") : ServiceResponse.createErrorResponse("操作失败");
    }

    @Override
    public List<Calculate> getCalculateByRecy() {
        CalculateExample calculateExample = new CalculateExample();
        CalculateExample.Criteria criteria = calculateExample.createCriteria();
        criteria.andTypeEqualTo(CalculateTypeEnum.TEMPORARY.getValue());
        Calendar theCa = Calendar.getInstance();
        theCa.setTime(new Date());
        theCa.add(theCa.DATE, -30);//最后一个数字30可改，30天的意思
        Date start = theCa.getTime();
        criteria.andCreateDateLessThan(start);
        criteria.andIsDeleteEqualTo(false);
        List<Calculate> calculates = calculateMapper.selectByExample(calculateExample);
        return calculates;
    }

    @Override
    public int editCalculate(Calculate calculate) {
        return calculateMapper.updateByPrimaryKeySelective(calculate);
    }

    @Override
    public List<Calculate> getCalculateByUserId(Long userId, PageFilter pageFilter) {
        CalculateExample calculateExample = new CalculateExample();
        CalculateExample.Criteria criteria = calculateExample.createCriteria();
        criteria.andIsDeleteEqualTo(false);
        criteria.andUserIdEqualTo(userId);
        calculateExample.setOrderByClause("create_date desc");
        PageHelper.startPage(pageFilter.getPageNum(), pageFilter.getPageSize());
        List<Calculate> calculateList = calculateMapper.selectByExample(calculateExample);

        return calculateList;
    }

    @Override
    public List<Calculate> getCalculateList(PageFilter pageFilter) {
        CalculateExample calculateExample = new CalculateExample();
        CalculateExample.Criteria criteria = calculateExample.createCriteria();
        Optional.ofNullable(pageFilter.getFilterMap().get("userId")).map(userId -> criteria.andUserIdEqualTo(Long.valueOf(userId)));
        criteria.andIsDeleteEqualTo(false);
        calculateExample.setOrderByClause(pageFilter.getOrderCause());
        PageHelper.startPage(pageFilter.getPageNum(), pageFilter.getPageSize());
        List<Calculate> calculates = calculateMapper.selectByExample(calculateExample);
        return calculates;
    }

    @Override
    public int deleteUserCalculate(Long userId) {
        CalculateExample calculateExample = new CalculateExample();
        CalculateExample.Criteria criteria = calculateExample.createCriteria();
        criteria.andUserIdEqualTo(userId);
        List<Calculate> calculates = calculateMapper.selectByExample(calculateExample);
        calculateMapper.deleteBatch(calculates);
        return 0;
    }

    @Transactional
    @Override
    public void calculateRecy() {
        List<Calculate> calculateByRecy = getCalculateByRecy();
        for (Calculate calculate : calculateByRecy) {
            //回收30天的临时算力
            Calculate newCalculate = new Calculate();
            newCalculate.setIsDelete(true);
            newCalculate.setId(calculate.getId());
            editCalculate(newCalculate);
            //减少用户总算力
            User userDetail = userService.getUserDetail(calculate.getUserId());
            User user = new User();
            user.setId(calculate.getUserId());
            user.setCalculate(userDetail.getCalculate() - calculate.getValue());
            userService.editUser(user);

        }
    }

    @Override
    public Long insertCalculate(Calculate calculate) {
        int insert = calculateMapper.insertSelective(calculate);
        if (insert <= 0) {
            throw new CustomerException("算力添加出错");
        }
        //更新用户算力
        User userDetail = userService.getUserDetail(calculate.getUserId());
        User newUser = new User();
        newUser.setCalculate(userDetail.getCalculate() + calculate.getValue());
        newUser.setVersion(userDetail.getVersion() + 1);
        UserExample userExample = new UserExample();
        UserExample.Criteria criteria = userExample.createCriteria();
        criteria.andVersionEqualTo(userDetail.getVersion());
        criteria.andIdEqualTo(userDetail.getId());
        int i = userService.updateUser(newUser, userExample);
        if (i <= 0) {
            throw new CustomerException("更新算力出错");
        }
        return calculate.getId();
    }

    @Override
    public Calculate getCalculateById(Long calculateId) {
        Calculate calculate = calculateMapper.selectByPrimaryKey(calculateId);
        return calculate;
    }

}
